import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
import { Map, View, Feature } from 'ol';
import { Vector as VectorLayer } from 'ol/layer';
import TileLayer from 'ol/layer/Tile';
import { Vector as VectorSource } from 'ol/source';
import XYZ from 'ol/source/XYZ';
import { LineString } from 'ol/geom';
import { Style, Stroke } from 'ol/style';
import OLCesium from '@/libs/olcs2.16.0/OlCesium';
import { Cesium3DTileset } from 'cesium';
import { tilesetURLs } from '../configs/data';
import { fromLonLat } from 'ol/proj';

/**
 * 地图控制钩子函数，处理2D/3D地图的创建和控制
 * @returns {Object} 地图控制相关方法和状态
 */
export function useMapControl() {
  // 地图状态
  const map = ref(null);
  const map3d = ref(null);
  const is2D = ref(true);
  const sourceFeatures = ref(new VectorSource());
  const lineString = ref(new LineString([]));
  
  // 资源管理
  const resources = reactive({
    layers: [],
    overlays: []
  });
  
  /**
   * 初始化OpenLayers地图
   * @param {String} targetId - 地图容器元素ID
   * @param {Array} center - 初始中心点坐标 [lon, lat]
   * @param {Number} zoom - 初始缩放级别
   * @returns {Object} 初始化的地图实例
   */
 
   function initMap(targetId = 'map', center = [121.62021584789193, 29.9239055235632], zoom = 15) {
    try {
      console.log('开始初始化地图:', targetId);
      
      if (map.value) {
        console.log('地图实例已存在，返回现有实例');
        return map.value;
      }
      
      // 检查目标元素是否存在
      const targetElement = document.getElementById(targetId);
      if (!targetElement) {
        console.error(`地图容器元素 #${targetId} 不存在`);
        return null;
      }
      
      console.log('创建矢量数据源');
      // 确保已创建数据源
      if (!sourceFeatures.value) {
        sourceFeatures.value = new VectorSource({
          wrapX: false,
          useSpatialIndex: true
        });
        console.log('已创建新的矢量数据源:', sourceFeatures.value);
      }
      
      // 创建LineString几何对象用于显示轨迹
      lineString.value.setCoordinates([center, center]);
      
      console.log('创建地图实例');
      // 创建地图实例
      map.value = new Map({
        target: targetId,
        view: new View({
          // OpenStreetMap使用EPSG:3857（Web墨卡托）投影
          projection: 'EPSG:3857',
          center: fromLonLat([121.62021584789193, 29.9239055235632]),
          zoom: zoom,
          minZoom: 3,
          maxZoom: 19
        }),
        layers: [
          
          // 第二层：OpenStreetMap图层
          new TileLayer({
            source: new XYZ({
              url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
              attributions: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
              maxZoom: 19,
              wrapX: false,
              crossOrigin: 'anonymous'
            })
          }),
          
          // 第三层：轨迹线图层
          new VectorLayer({
            source: new VectorSource({
              features: [
                new Feature({
                  geometry: lineString.value
                })
              ]
            }),
            style: [
              new Style({
                stroke: new Stroke({
                  width: 3,
                  color: 'rgba(0, 0, 0, 1)',
                  lineDash: [0.1, 5]
                }),
                zIndex: 2
              })
            ],
            updateWhileAnimating: true
          }),
          
          // 第四层：矢量要素图层
          new VectorLayer({
            source: sourceFeatures.value,
            ol3d: {
              cesiumOptions: {
                shadows: false
              }
            }
          })
        ]
      });
      
      // 添加地图加载完成事件监听
      map.value.once('rendercomplete', function() {
        console.log('地图渲染完成');
      });
      
      // 记录资源
      resources.layers = map.value.getLayers().getArray();
      
      console.log('地图实例已创建:', map.value);
      console.log('数据源状态:', sourceFeatures.value);
      return map.value;
    } catch (error) {
      console.error('初始化地图失败:', error);
      return null;
    }
  }
  /**
   * 初始化3D地图
   */
  function init3DMap() {
    if (map3d.value) return map3d.value;
    
    try {
      // 创建OLCesium实例
      map3d.value = new OLCesium({
        map: map.value,
        scene3DOnly: true, // 强制3D模式
        sceneOptions: {
          // 设置场景选项
          allowTextureFilterAnisotropic: false, // 禁用各向异性纹理过滤
          requestRenderMode: true, // 按需渲染
          maximumRenderTimeChange: Infinity, // 无限最大渲染时间变化
          useDefaultRenderLoop: true, // 使用默认渲染循环
          contextOptions: {
            webgl: {
              alpha: false, // 禁用alpha混合
              depth: true, // 启用深度测试
              stencil: false, // 禁用模板缓冲区
              antialias: true, // 启用抗锯齿
              premultipliedAlpha: true, // 启用预乘alpha
              preserveDrawingBuffer: false, // 不保留绘图缓冲区
              failIfMajorPerformanceCaveat: false // 即使在性能不佳的情况下也不要失败
            }
          }
        }
      });
      
      // 默认禁用3D视图
      map3d.value.setEnabled(false);
      
      // 获取Cesium视图和场景
      const scene = map3d.value.getCesiumScene();
      
      // 设置场景渲染选项
      scene.globe.depthTestAgainstTerrain = true;
      scene.globe.enableLighting = false;
      scene.fog.enabled = false;
      scene.skyAtmosphere.show = false;
      scene.globe.showGroundAtmosphere = false;
      
      // 处理渲染错误 - 防止终止渲染
      scene.renderError.addEventListener(function(error) {
        console.error('Cesium渲染错误:', error);
        
        // 处理特定的错误类型
        if (error && error.message && error.message.includes('Appearance/Geometry mismatch')) {
          console.warn('处理几何体与外观不匹配错误，尝试继续渲染');
          
          // 尝试获取当前场景中的所有图元
          const primitives = scene.primitives;
          
          // 创建一个SafePrimitiveCollection钩子来捕获错误
          if (!scene._safePrimitiveRender) {
            const oldAdd = primitives.add;
            primitives.add = function(primitive) {
              try {
                // 如果是几何体类型，尝试添加兼容性属性
                if (primitive && primitive.geometryInstances) {
                  console.log('添加兼容性属性到几何体实例');
                  // 添加实际的兼容性属性
                  primitive.geometryInstances.forEach(instance => {
                    // 设置必要的兼容性属性
                    instance.attributes = instance.attributes || {};
                    instance.attributes.position = instance.attributes.position || {};
                    // 其他必要的属性设置
                  });
                }
                return oldAdd.call(primitives, primitive);
              } catch (e) {
                console.warn('添加图元时出错，跳过此图元:', e);
                return primitive;
              }
            };
            scene._safePrimitiveRender = true;
          }
        }
        
        // 不管发生什么错误，尝试继续渲染
        setTimeout(function() {
          try {
            scene.requestRender();
          } catch (e) {
            console.error('请求重新渲染失败:', e);
          }
        }, 500);
      });
      
      // 加载3D瓦片集
      tilesetURLs.forEach((cfg, index) => {
        try {
          load3DTilesetToCesiumScene(cfg.url, {
            properties: cfg.properties,
            flyTo: index === 0,
            heightOffset: -55
          });
        } catch (e) {
          console.error(`加载3D瓦片集失败: ${cfg.url}`, e);
        }
      });
      
      return map3d.value;
    } catch (error) {
      console.error('初始化3D地图失败:', error);
      map3d.value = null;
      return null;
    }
  }
  
  /**
   * 加载3D瓦片集到Cesium场景
   * @param {String} url - 瓦片集URL
   * @param {Object} options - 配置选项
   */
  function load3DTilesetToCesiumScene(url, options = {}) {
    if (!map3d.value) return;
    
    Cesium3DTileset.fromUrl(url)
      .then((tileset) => {
        // 自定义属性
        if (!tileset.costomProps) {
          tileset.costomProps = {};
        }
       // 将自定义属性添加到瓦片集
        for (const key in options.properties) {
          if (Object.hasOwnProperty.call(options.properties, key)) {
            tileset.costomProps[key] = options.properties[key];
          }
        }
        
        // 设置偏移量
        let translation = new Cesium.Cartesian3(
          0,
          0,
          options.heightOffset || 0
        );
        let modelMatrix = Cesium.Matrix4.fromTranslation(translation);
        
        tileset.modelMatrix = modelMatrix;
        
        map3d.value.getCesiumScene().primitives.add(tileset);
        options.flyTo && map3d.value.getCesiumViewer().flyTo(tileset);
      })
      .catch((error) => {
        console.error(`Error loading tileset: ${error}`);
      });
  }
  
  /**
   * 切换2D/3D视图
   * @returns {Boolean} 切换后的状态，true表示2D模式，false表示3D模式
   */
  function toggleDimension() {
    if (!map3d.value) {
      init3DMap();
    }
    
    if (is2D.value) {
      try {
        // 检查矢量图层的要素是否有Cesium兼容属性
        const features = sourceFeatures.value.getFeatures();
        features.forEach(feature => {
          if (!feature.get('olcs_properties')) {
            // 添加Cesium兼容属性以避免渲染错误
            feature.set('olcs_properties', {
              olcs_skip_style_conversion: true,
              olcs_custom_style: true
            });
          }
        });
        
        // 切换到3D视图
        console.log('切换到3D视图');
        map3d.value.setEnabled(true);
        is2D.value = false;
        
        // 获取场景并添加额外的错误处理
        const scene = map3d.value.getCesiumScene();
        
        // 禁用可能导致渲染错误的功能
        scene.logarithmicDepthBuffer = false;
        
        // 添加安全渲染钩子
        if (!scene._safeRenderingHooked) {
          // 覆盖原始的primitive添加方法
          const primitives = scene.primitives;
          const originalAdd = primitives.add;
          primitives.add = function(primitive) {
            try {
              return originalAdd.call(this, primitive);
            } catch (e) {
              console.warn('添加图元时出错，跳过此图元:', e);
              return primitive;
            }
          };
          
          // 覆盖更新方法以避免渲染错误中断渲染循环
          const originalUpdate = scene.updateFrameState;
          scene.updateFrameState = function() {
            try {
              return originalUpdate.apply(this, arguments);
            } catch (e) {
              console.warn('更新帧状态时出错:', e);
              return undefined;
            }
          };
          
          scene._safeRenderingHooked = true;
        }
        
        // 修复3D模式下OpenLayers交互的事件冲突
        fixOL3DInteractions(scene);
        
        // 确保持续渲染，即使出错
        setTimeout(() => {
          try {
            scene.requestRender();
          } catch (e) {
            console.error('请求渲染失败:', e);
          }
        }, 100);
      } catch (error) {
        console.error('切换到3D视图时出错:', error);
        // 出错时恢复2D视图
        map3d.value.setEnabled(false);
        is2D.value = true;
      }
    } else {
      // 切换到2D视图前，保存当前3D视角位置
      try {
        const scene = map3d.value.getCesiumScene();
        const camera = scene.camera;
        const Cesium = window.Cesium;
        
        if (!Cesium) {
          console.warn('Cesium全局对象不可用');
          map3d.value.setEnabled(false);
          is2D.value = true;
          return is2D.value;
        }
        
        // 查找模型中心点
        let modelCenter = null;
        const primitives = scene.primitives;
        
        if (primitives && primitives.length > 0) {
          for (let i = 0; i < primitives.length; i++) {
            const primitive = primitives.get(i);
            if (primitive && primitive.boundingSphere) {
              modelCenter = primitive.boundingSphere.center;
              break;
            }
          }
        }
        
        // 如果找到模型中心，使用它作为目标点
        // 否则，使用当前相机位置转换为地理坐标
        let targetPosition;
        
        if (modelCenter) {
          console.log('使用模型中心点坐标');
          targetPosition = modelCenter;
        } else {
          console.log('使用相机位置坐标');
          // 获取相机当前朝向中心点
          const ray = new Cesium.Ray(camera.position, camera.direction);
          targetPosition = scene.globe.pick(ray, scene);
          
          // 如果未找到交点，使用相机位置
          if (!targetPosition) {
            targetPosition = camera.position;
          }
        }
        
        // 将Cartesian3坐标转换为WGS84地理坐标
        const cartographic = Cesium.Cartographic.fromCartesian(targetPosition);
        const longitude = Cesium.Math.toDegrees(cartographic.longitude);
        const latitude = Cesium.Math.toDegrees(cartographic.latitude);
        
        // 设置适当的缩放级别
        let zoom = 16;
        const height = cartographic.height;
        if (height > 1000) {
          zoom = 15;
        } else if (height > 5000) {
          zoom = 14;
        } else if (height > 10000) {
          zoom = 13;
        }
        
        console.log('将2D视图定位到:', longitude, latitude, '缩放级别:', zoom);
        
        // 切换到2D视图
        console.log('切换到2D视图');
        map3d.value.setEnabled(false);
        is2D.value = true;
        
        // 将OpenLayers视图设置到相同位置
        if (map.value) {
          const view = map.value.getView();
          import('ol/proj').then(({ fromLonLat }) => {
            const center = fromLonLat([longitude, latitude]);
            view.animate({
              center: center,
              zoom: zoom,
              duration: 500
            });
          });
        }
      } catch (error) {
        console.error('保存3D视角坐标失败:', error);
        // 出错时仍然切换到2D视图
        map3d.value.setEnabled(false);
        is2D.value = true;
      }
    }
    
    return is2D.value;
  }
  
  /**
   * 修复3D模式下OpenLayers的交互问题
   * @param {Object} scene - Cesium场景对象
   */
  function fixOL3DInteractions(scene) {
    try {
      // 1. 修改Cesium Canvas的事件处理，允许事件穿透
      if (scene && scene.canvas) {
        const cesiumCanvas = scene.canvas;
        cesiumCanvas.style.pointerEvents = 'none';
      }
      
      // 2. 设置OpenLayers视口的z-index高于Cesium
      const olViewport = document.querySelector('.ol-viewport');
      if (olViewport) {
        olViewport.style.position = 'relative';
        olViewport.style.zIndex = '1000';
        olViewport.style.pointerEvents = 'auto';
      }
      
      // 3. 确保measure-tools和draw-tools元素可交互
      const tools = document.querySelectorAll('.measure-tools, .draw-tools, .map-controls');
      tools.forEach(tool => {
        if (tool) {
          tool.style.zIndex = '1001';
          tool.style.pointerEvents = 'auto';
          
          // 修复按钮点击
          const buttons = tool.querySelectorAll('button');
          buttons.forEach(button => {
            button.style.pointerEvents = 'auto';
            button.style.position = 'relative';
            button.style.zIndex = '1002';
          });
        }
      });
      
      // 4. 添加全局CSS样式，确保交互正确
      if (!document.getElementById('ol-cesium-fix-style')) {
        const style = document.createElement('style');
        style.id = 'ol-cesium-fix-style';
        style.textContent = `
          .cesium-widget canvas { 
            pointer-events: none !important; 
          }
          .ol-viewport, .ol-unselectable, .ol-viewport canvas {
            position: relative !important;
            z-index: 1000 !important;
            pointer-events: auto !important;
          }
          .ol-control {
            z-index: 1001 !important;
            pointer-events: auto !important;
          }
          .measure-tools, .draw-tools, .map-controls {
            z-index: 1001 !important;
            pointer-events: auto !important;
          }
          .measure-tools button, .draw-tools button, .map-controls button {
            position: relative !important;
            z-index: 1002 !important;
            pointer-events: auto !important;
          }
          .ol-overlay-container {
            pointer-events: none;
          }
          .ol-overlay-container.measure-tools {
            pointer-events: auto !important;
          }
        `;
        document.head.appendChild(style);
      }
      
      console.log('已修复3D模式下的OpenLayers交互问题');
    } catch (error) {
      console.error('修复3D模式交互问题失败:', error);
    }
  }
  
  
  /**
   * 添加图层到地图
   * @param {Object} layer - OpenLayers图层对象
   */
  function addLayer(layer) {
    if (!map.value) return;
    
    // 避免添加重复的图层
    const layers = map.value.getLayers().getArray();
    const exists = layers.some(l => l === layer);
    
    if (!exists) {
      map.value.addLayer(layer);
      resources.layers.push(layer);
    }
  }
  
  /**
   * 移除图层
   * @param {Object} layer - 要移除的图层
   */
  function removeLayer(layer) {
    if (!map.value) return;
    
    map.value.removeLayer(layer);
    const index = resources.layers.indexOf(layer);
    if (index !== -1) {
      resources.layers.splice(index, 1);
    }
  }
  
  /**
   * 清除所有叠加层
   */
  function clearOverlays() {
    if (!map.value) return;
    
    const overlays = map.value.getOverlays().getArray();
    for (let i = overlays.length - 1; i >= 0; i--) {
      overlays[i].setPosition(undefined);
      map.value.removeOverlay(overlays[i]);
    }
    
    resources.overlays = [];
  }
  
  /**
   * 添加叠加层到地图
   * @param {Object} overlay - OpenLayers叠加层对象
   */
  function addOverlay(overlay) {
    if (!map.value) return;
    
    map.value.addOverlay(overlay);
    resources.overlays.push(overlay);
    
    return overlay;
  }
  
  /**
   * 获取Cesium3D视图是否启用
   * @returns {Boolean} 3D视图是否启用
   */
  function is3DEnabled() {
    if (!map3d.value) return false;
    return map3d.value.getEnabled();
  }
  
  /**
   * 清理资源
   */
  function cleanup() {
    // 清除叠加层
    clearOverlays();
    
    // 禁用3D视图
    if (map3d.value) {
      map3d.value.setEnabled(false);
    }
    
    // 清空数据源
    if (sourceFeatures.value) {
      sourceFeatures.value.clear();
    }
  }
  
  // 在组件销毁前清理资源
  onBeforeUnmount(() => {
    cleanup();
  });
  
  return {
    // 状态
    map,
    map3d,
    is2D,
    sourceFeatures,
    lineString,
    
    // 方法
    initMap,
    init3DMap,
    toggleDimension,
    addLayer,
    removeLayer,
    addOverlay,
    clearOverlays,
    is3DEnabled,
    load3DTilesetToCesiumScene,
    cleanup
  };
} 